package exam;

import com.spm.dao.StudentGradeMapper;
import com.spm.utils.StudentGradeMapperUtil;
import com.spm.utils.StudentMapperUtil;
import exam.bean.StuInfo;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Enumeration;
import java.util.HashMap;

@WebServlet(name = "MarkServlet", value = "/MarkServlet")
public class MarkServlet extends HttpServlet {

    private ServletContext context;

    //单选题标志
    static final String SINGLE = "single";

    //多选题标志
    static final String MULTI = "multi";

    //对错题标志
    static final String JUDGE = "judge";

    //填空题标志
    static final String FILL = "fill";

    //简单题标志
    static final String QUERY = "query";

    //每道题的分值
    static final int score = 4;
    private String sid;
    private String tid;
    private String cno;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        context = config.getServletContext();
        //从文件中读取标准答案，得到答案存储map对象到context中，只需操作一次
        context.setAttribute("answer",getMapAnswer());
    }

    protected HashMap<String, String> getMapAnswer() {
        HashMap<String, String> mapAnswer = null;
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("../answer.txt"));
            mapAnswer = (HashMap<String, String>) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return mapAnswer;
    }
    //将多选题的答案按字母排序，如传递的值为CB，排序为BC
    protected String sortMultiAnswer(String multiAnswer) {
        char[] charArray = multiAnswer.toCharArray();
        for (int i = charArray.length - 1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if (charArray[j] > charArray[j + 1]) {
                    char temp;
                    temp = charArray[j];
                    charArray[j] = charArray[j + 1];
                    charArray[j + 1] = temp;
                }
            }
        }
         return new String(charArray);
    }

    protected void getMark(HttpServletRequest request,StuInfo stuInfo) {
        HashMap<String,String> mapAnswer = (HashMap<String, String>) context.getAttribute("answer");
        int grade = 0;
        Enumeration<String> pns = request.getParameterNames();
        while (pns.hasMoreElements()) {
            String key = pns.nextElement();
            String value;
            if(key.contains(MULTI)){
                String[] values = request.getParameterValues(key);
                StringBuffer sb = new StringBuffer();
                for(int i = 0; i < values.length; i++){
                    sb.append(values[i]);
                }
                value = sb.toString();
            }
            else{
                value = request.getParameter(key);
            }
            //判断是否为学生姓名
            if ("name".equals(key)) {
                stuInfo.setStuName(value);
            }
            //判断是否为学生学号
            else if ("id".equals(key)) {
                stuInfo.setStuId(value);
            }
            //答题情况
            else {
                //这道题是单选题、对错题或填空题
                if (key.contains(SINGLE) || key.contains(JUDGE) || key.contains(FILL)) {
                    if (mapAnswer.get(key).equals(value)) {
                        grade += score;
                    }
                }
                //这道题是多选题
                else if (key.contains(MULTI)) {
                    if (value != null) {
                        if(mapAnswer.get(key).equals(sortMultiAnswer(value))) {
                            grade += score;
                        }
                    }
                }
                //这道题是简答题
                else if(key.contains(QUERY)) {
                    String[] split = mapAnswer.get(key).split("、");
                    for(int i = 0; i < split.length; i++) {
                        if(!value.contains(split[i])){
                            break;
                        }
                        else if(i == split.length - 1){
                            grade += score;
                        }
                    }
                }
            }
        }
        stuInfo.setGrade(grade);

    }

    protected void storeStuInfo(StuInfo stuInfo) {
        File file = new File("../stuInfo.txt");
        try {
            ObjectOutputStreamForAdding oos = ObjectOutputStreamForAdding.newInstance(file,new FileOutputStream(file,true));
            oos.writeObject(stuInfo);
            oos.flush();
            oos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        StudentGradeMapperUtil studentGradeMapperUtil = new StudentGradeMapperUtil();
        studentGradeMapperUtil.updateFinalGrade(sid,tid,cno,stuInfo.getGrade());
    }


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        sid = request.getParameter("id");
        cno = request.getParameter("course");
        tid = request.getParameter("teacher");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        StuInfo stuInfo = new StuInfo();
        request.setCharacterEncoding("utf-8");
        //根据map对象中存储的答案进行判分
        getMark(request,stuInfo);
        //存储结果到文件中并显示结果
        storeStuInfo(stuInfo);

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head><title>得分情况</title></head>");
        out.println("<body>");
        out.println("<script>");
        out.println("window.alert('"+stuInfo.getStuName()+"同学，您取得了"+stuInfo.getGrade()+"分的成绩！"+"');window.location.href='./homepage.html'");
        out.println("</script>");
        out.println("</body></html>");
        out.close();
    }

    static class ObjectOutputStreamForAdding extends ObjectOutputStream{
        private static File f;

        public static ObjectOutputStreamForAdding newInstance(File file,OutputStream out) throws IOException {
            f = file;
            return new ObjectOutputStreamForAdding(out);
        }

        private ObjectOutputStreamForAdding(OutputStream out) throws IOException {
            super(out);
        }

        @Override
        protected void writeStreamHeader() throws IOException {
            if(!f.exists() || (f.exists() && (f.length()) == 0)){
                super.writeStreamHeader();
            }else{
                super.reset();
            }
        }
    }

}
